using MediatR;
using Microsoft.EntityFrameworkCore;
using System.Security.Cryptography;
using System.Text;
using Traceability.API.APPLications.Commands.Login;
using Traceability.API.Dtos;
using Traceability.API.Services;
using Traceability.Domain;
using Traceability.ErrorCode;
using Traceability.Infrastructure;

namespace Traceability.API.APPLications.CommandHanders.Login
{
    public class LoginQueryHandler : IRequestHandler<LoginQueryCommand, APIResult<LoginResponseDto>>
    {
        private readonly IBaseRepository<User> _userRepository;
        private readonly IBaseRepository<UserRole> _userRoleRepository;
        private readonly IBaseRepository<Role> _roleRepository;
        private readonly JwtService _jwtService;
        private readonly RedisCaptchaService _redisCaptchaService;

        public LoginQueryHandler(
            IBaseRepository<User> userRepository,
            IBaseRepository<UserRole> userRoleRepository,
            IBaseRepository<Role> roleRepository,
            JwtService jwtService,
            RedisCaptchaService redisCaptchaService)
        {
            _userRepository = userRepository;
            _userRoleRepository = userRoleRepository;
            _roleRepository = roleRepository;
            _jwtService = jwtService;
            _redisCaptchaService = redisCaptchaService;
        }

        public async Task<APIResult<LoginResponseDto>> Handle(LoginQueryCommand request, CancellationToken cancellationToken)
        {
            try
            {
                // 参数验证
                if (string.IsNullOrEmpty(request.UserName) || string.IsNullOrEmpty(request.Password))
                {
                    return new APIResult<LoginResponseDto>
                    {
                        Code = APIEnum.登录失败,
                        Message = "用户名和密码不能为空",
                        Data = null
                    };
                }

                // 验证码验证
                if (string.IsNullOrEmpty(request.CaptchaId) || string.IsNullOrEmpty(request.CaptchaCode))
                {
                    return new APIResult<LoginResponseDto>
                    {
                        Code = APIEnum.登录失败,
                        Message = "验证码不能为空",
                        Data = null
                    };
                }

                // 验证验证码
                bool isCaptchaValid = await _redisCaptchaService.ValidateCaptchaAsync(request.CaptchaId, request.CaptchaCode);
                if (!isCaptchaValid)
                {
                    return new APIResult<LoginResponseDto>
                    {
                        Code = APIEnum.登录失败,
                        Message = "验证码错误或已过期",
                        Data = null
                    };
                }

                // 对密码进行MD5加密
                string encryptedPassword = EncryptMD5(request.Password);

                // 查询用户
                var user = await _userRepository.GetAll()
                    .FirstOrDefaultAsync(u => u.UserName == request.UserName && u.Password == encryptedPassword, cancellationToken);

                if (user == null)
                {
                    return new APIResult<LoginResponseDto>
                    {
                        Code = APIEnum.登录失败,
                        Message = "用户名或密码错误",
                        Data = null
                    };
                }

                // 查询用户角色
                var userRole = await _userRoleRepository.GetAll()
                    .FirstOrDefaultAsync(ur => ur.UserId == user.UserId, cancellationToken);

                if (userRole == null)
                {
                    return new APIResult<LoginResponseDto>
                    {
                        Code = APIEnum.登录失败,
                        Message = "用户未分配角色",
                        Data = null
                    };
                }

                // 查询角色信息
                var role = await _roleRepository.GetAll()
                    .FirstOrDefaultAsync(r => r.RoleId == userRole.RoleId, cancellationToken);

                // 构建用户信息
                var userDto = new UserDto
                {
                    UserId = user.UserId,
                    URId = userRole.URId,
                    UserName = user.UserName,
                    UserNickName = user.UserNickName,
                    RoleId = userRole.RoleId,
                    RoleName = role?.RoleName ?? string.Empty
                };

                // 生成JWT Token
                string token = _jwtService.GenerateToken(userDto);

                // 构建登录响应
                var loginResponse = new LoginResponseDto
                {
                    User = userDto,
                    Token = token,
                    ExpiresAt = DateTime.Now.AddHours(24),
                    LoginTime = DateTime.Now
                };

                return new APIResult<LoginResponseDto>
                {
                    Code = APIEnum.登录成功,
                    Message = "登录成功",
                    Data = loginResponse
                };
            }
            catch (Exception ex)
            {
                return new APIResult<LoginResponseDto>
                {
                    Code = APIEnum.登录失败,
                    Message = $"登录过程中发生错误: {ex.Message}",
                    Data = null
                };
            }
        }

        private string EncryptMD5(string input)
        {
            using (MD5 md5 = MD5.Create())
            {
                byte[] inputBytes = Encoding.UTF8.GetBytes(input);
                byte[] hashBytes = md5.ComputeHash(inputBytes);

                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < hashBytes.Length; i++)
                {
                    sb.Append(hashBytes[i].ToString("x2"));
                }
                return sb.ToString();
            }
        }
    }
} 